package com.lechuang.order.controller;

import cn.hutool.core.lang.Pair;
import cn.hutool.json.JSONUtil;
import com.lechuang.common.request.PageRequest;
import com.lechuang.common.result.PageResult;
import com.lechuang.common.result.Result;
import com.lechuang.file.dto.ExportClassDTO;
import com.lechuang.file.dto.ExportStringDTO;
import com.lechuang.file.utils.ReadExcelUtils;
import com.lechuang.file.utils.WriteExcelUtils;
import com.lechuang.goods.feign.TestFeign;
import com.lechuang.mq.client.RabbitMqClient;
import com.lechuang.order.excel.ExcelDTO;
import com.lechuang.order.entity.Test;
import com.lechuang.order.excel.ImportExcelDTO;
import com.lechuang.order.manager.TestManager;
import com.lechuang.order.mq.MqConstant;
import com.lechuang.redis.utils.RedisUtils;
import com.lechuang.thread.util.ThreadUtil;
import com.lechuang.web.exception.BusinessException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.log4j.Log4j2;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;

@RestController
@RequestMapping("/test")
@Log4j2
@Tag(name = "测试接口类")
public class TestController {

    @Resource
    private TestManager testManager;
    @Resource
    private TestFeign testFeign;
    @Resource
    private RabbitMqClient rabbitMqClient;

    @Operation(summary = "新增、查询接口")
    @PostMapping("/mybatis")
    public Result<List<Test>> mybatis(@RequestParam String name){
        testManager.insert(name);
        List<Test> list = testManager.list();
        return Result.success(list);
    }

    @Operation(summary = "分页查询接口")
    @PostMapping("/mybatisPage")
    private Result<PageResult<Test>> mybatisTest1(@RequestBody PageRequest<String> pageRequest){
        PageResult<Test> pageResult = testManager.page(pageRequest);
        return Result.success(pageResult);
    }

    @Operation(summary = "异常接口")
    @PostMapping("/exceptionTest")
    private Result<String> exceptionTest(){
        log.error("exceptionTest");
        throw new BusinessException("exceptionTest");
    }

    @Operation(summary = "excel导出接口，表头是类")
    @GetMapping("/exportExcelByClassHeader")
    public void exportExcelByClassHeader(HttpServletResponse httpServletResponse){
        log.info("excel导出测试接口");
        ExcelDTO excelDTO = new ExcelDTO();
        excelDTO.setName("商品1");
        excelDTO.setPrice(new BigDecimal("22.22"));
        excelDTO.setCreateTime(new Date());
        excelDTO.setUpdateTime(new Date());
        ExportClassDTO exportClassDTO = new ExportClassDTO()
                .setHttpServletResponse(httpServletResponse)
                .setFileName("文件名")
                .setSheetName("sheet名")
                .setTitle("这是一个标题")
                .setRemarkList(Arrays.asList("第一行备注", "第二行备注"))
                .setDataList(Arrays.asList(excelDTO))
                .setDataClass(ExcelDTO.class)
                .setMergeRowIndex(0)
                .setMergeColumnIndex(new int[0]);
        WriteExcelUtils.exportExcel(exportClassDTO);
    }

    @Operation(summary = "excel导出接口，表头是字符串集合")
    @GetMapping("exportExcelByStringHeader")
    public void exportExcelByStringHeader(HttpServletResponse httpServletResponse){
        log.info("excel导出测试接口2");
        List<List<String>> heads = new ArrayList<>();
        List<String> head1 = Arrays.asList("商品名称", "商品名称");
        List<String> head2 = Arrays.asList("单价", "单价");
        List<String> head3 = Arrays.asList("时间", "创建时间");
        List<String> head4 = Arrays.asList("时间", "修改时间");
        heads.add(head1);
        heads.add(head2);
        heads.add(head3);
        heads.add(head4);

        List<List<Object>> dataList = new ArrayList<>();
        List<Object> list = Arrays.asList("商品1", new BigDecimal("22.22"), new Date(), new Date());
        dataList.add(list);

        ExportStringDTO exportStringDTO = new ExportStringDTO()
                .setHttpServletResponse(httpServletResponse)
                .setFileName("文件名")
                .setSheetName("sheet名")
                .setTitle("这是一个标题")
                .setRemarkList(Arrays.asList("第一行备注", "第二行备注"))
                .setDataList(dataList)
                .setHeads(heads)
                .setMergeRowIndex(0)
                .setMergeColumnIndex(new int[0]);

        WriteExcelUtils.exportExcel(exportStringDTO);
    }

    @Operation(summary = "excel导入接口")
    @PostMapping("importExcel")
    public void test(@RequestPart @RequestParam(value = "file") MultipartFile file){
        Pair<Map<Integer, String>, List<ImportExcelDTO>> mapListPair = ReadExcelUtils.analysisExcel(file, ImportExcelDTO.class, 0, 1);
        List<ImportExcelDTO> list = mapListPair.getValue();
        log.info(JSONUtil.toJsonStr(list));
    }

    @Operation(summary = "feign测试接口")
    @PostMapping("feignTest")
    public Result<String> feignTest(){
        log.info("feignTest");
        return testFeign.test();
    }

    @PostMapping("/threadTest")
    @Operation(summary = "多线程测试")
    private Result<String> threadTest(){
        ThreadPoolTaskExecutor threadPoolTaskExecutor = ThreadUtil.getThreadPoolTaskExecutor();
        for (int i = 0; i < 20; i++) {
            int a = i;
            CompletableFuture.runAsync(() -> {
                log.info("threadTest,i={}", a);
            }, threadPoolTaskExecutor);
        }
        return Result.success();
    }

    @PostMapping("/redisTest")
    @Operation(summary = "redis测试")
    private Result<Object> redisTest(){
        RedisUtils.set("key", "hello Redis");
        Object value = RedisUtils.get("key");
        return Result.success(value);
    }

    @PostMapping("/mqTest1")
    @Operation(summary = "mq测试-普通消息")
    public Result<String> test1(){
        log.info("发送普通消息");
        rabbitMqClient.sendMessage(MqConstant.MQ_EXCHANGE,"", "普通消息");
        return Result.success();
    }

    @PostMapping("/mqTest2")
    @Operation(summary = "mq测试-延迟消息")
    public Result<String> test2(){
        log.info("发送延迟消息");
        rabbitMqClient.sendDelayMessage(MqConstant.MQ_DELAYED_EXCHANGE,"", "延迟消息", MqConstant.DELAYED_TIME);
        return Result.success();
    }

    @PostMapping("/mqTest3")
    @Operation(summary = "mq测试-广播消息")
    public Result<String> test3(){
        log.info("发送广播消息");
        rabbitMqClient.sendMessage(MqConstant.MQ_BROADCAST_EXCHANGE,"", "广播消息");
        return Result.success();
    }

}
